home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 15
/
AMIGAplus Sonderheft 15 (1998)(ICP)(DE)[!].iso
/
rexx
/
saveanimgif.pprx
< prev
next >
Wrap
Text File
|
1997-06-01
|
18KB
|
641 lines
/* Personal Paint Amiga Rexx script - Copyright © 1996, 1997 Cloanto Italia srl */
/* $VER: SaveAnimGif.pprx 1.7 */
/** ENG
This script saves the current anim-brush as a GIF animation file. Specific
features of the GIF animation specification can be set through a requester.
This script checks for the differences between frames and only stores
the smallest rectangular region containing changes. Other techniques
are employed for additional compression. The resulting GIF animations are
highly optimized and occupy considerably less space than GIF animations
created with other tools available on the Amiga.
The "Use Loop" option inserts an "Application Extension Block" into the GIF
file (as implemented by Netscape in its Navigator software from version 2).
This additional block, which is interpreted by most other browsers
supporting GIF animations, specifies that the animation be repeated as many
times as indicated by the "Loop" value. A value of 0 expressly means
"loop continuously".
The list of frames shows the timing value for each frame, in seconds/100.
These values can be selected, edited and applied to one or more frames.
Alternatively, the timing can be copied automatically from the current
animation. If this option is selected ("From Animation"), then the
"Delay" value is used to indicate from which animation frame the timing
values are to be copied.
The "Transparency" setting indicates the current transparency status of
the anim-brush. If transparency is not required by the animation, it is
recommended to leave this option disabled.
Note: an "anim-brush" is a part of a full-screen animation. It can be
either loaded or defined manually after clicking three times on the
Define Brush tool.
*/
/** DEU
Dieses Skript dient zum Speichern des aktuellen Anim-Brushes als
GIF-Animation. Eine Reihe spezifischer Merkmale des Animationsformats läßt
sich in einem dazugehörigen Dialogfenster auswählen.
Nach der Skriptausführung werden zwei aufeinanderfolgende Frames zunächst
auf Unterschiede untersucht. Gespeichert wird dann nur der kleinste
rechteckige Bereich, der Unterschiede zwischen den beiden Bildern aufweist.
Außerdem werden zum Erzielen einer weiter verbesserten Komprimierung noch
andere Verfahren angewendet. Die daraus resultierenden hochoptimierten
GIF-Animationen benötigen erheblich weniger Speicherplatz als solche, die
mit anderen für den Amiga erhältlichen Tools erstellt worden sind.
Durch die Option "Schleife aktiv:" wird der GIF-Datei eine
Programmerweiterung ("Application Extension Block") hinzugefügt, wie sie von
Netscape im Navigator ab Version 2 implementiert ist. Dieser auch von den
meisten anderen Browsern, die GIF-Animationen unterstützen, interpretierte
Block legt fest, daß die Animation so oft wiederholt wird, wie unter
"Schleife:" angegeben. Ein Wert von 0 bewirkt das Abspielen in einer
Endlosschleife.
Die Frameliste zeigt den Timingwert für jedes Einzelbild in Hundertstel
Sekunden. Diese Werte lassen sich auswählen, bearbeiten und anschließend
einem oder mehreren Einzelbildern zuweisen. Alternativ dazu können die
Timingwerte automatisch aus der aktuellen Animation kopiert werden. Wenn die
entsprechende Option aktiviert ist ("Von Animation"), wird der
"Verzögerung"-Wert verwendet, um anzuzeigen, von welchem Einzelbild der
Animation die Timingwerte kopiert werden sollen.
Die "Transparenz"-Einstellung gibt den aktuellen Transparenzstatus des
Animationspinsels wieder. Erfordert die Animation keine Transparenz, so wird
empfohlen, diese Option ausgeschaltet zu lassen.
Hinweis: Ein Animationspinsel ist ein Bestandteil einer normalen Animation.
Er läßt sich nach einem Dreifachklick auf das Pinseldefinitionswerkzeug
entweder laden oder manuell definieren.
*/
/** ITA
Questo script salva l'anim-brush corrente come un'animazione GIF. Si possono
impostare le caratteristiche peculiari di una animazione GIF tramite una
apposita finestra di dialogo.
Questo script controlla eventuali differenze tra fotogrammi e salva solo
la più piccola regione rettangolare che contiene modifiche. Altre tecniche
sono utilizzate per una compressione aggiuntiva. Le animazioni GIF risultanti
sono altamente ottimizzate ed occupano molto meno spazio di quelle create con
altri programmi disponibili su Amiga.
L'opzione "Usare ciclo" inserisce un "Application Extension Block" nel file GIF
(come implementato da Netscape nel suo programma Navigator a partire dalla
versione 2). Questo blocco aggiuntivo, che viene interpretato dalla maggior
parte degli altri programmi di navigazione che permettono l'uso di animazioni
GIF, specifica che l'animazione deve essere ripetuta tante volte quante
indicato dal valore "Ciclo". Un valore pari a 0 significa espressamente
"ciclo continuo".
L'elenco dei fotogrammi mostra il valore di temporizzazione per ciascun
fotogramma, in centesimi di secondo. Tali valori possono essere selezionati,
modificati e applicati a uno o più fotogrammi. In alternativa, la
temporizzazione può essere copiata automaticamente dall'animazione corrente.
Se questa opzione è attiva ("Da animazione"), si usa il valore di
"Temporizzazione fotogrammi" per indicare da quale fotogramma dell'animazione
si devono copiare i valori di temporizzazione.
L'impostazione di "Trasparenza" indica lo stato attuale della trasparenza
dell'anim-brush. Se l'animazione non richiede la trasparenza, è consigliabile
lasciare disattivata questa opzione.
Nota: un "anim-brush" è un pennello, e come tale in genere una (più piccola)
parte di un'animazione a tutto schermo. Un anim-brush può essere caricare,
oppure definito manualmente facendo click tre volte sullo strumento
Definire pennello.
*/
IF ARG(1, EXISTS) THEN
PARSE ARG PPPORT
ELSE
PPPORT = 'PPAINT'
IF ~SHOW('P', PPPORT) THEN DO
IF EXISTS('PPaint:PPaint') THEN DO
ADDRESS COMMAND 'Run >NIL: PPaint:PPaint'
DO 30 WHILE ~SHOW('P',PPPORT)
ADDRESS COMMAND 'Wait >NIL: 1 SEC'
END
END
ELSE DO
SAY "Personal Paint could not be loaded."
EXIT 10
END
END
IF ~SHOW('P', PPPORT) THEN DO
SAY 'Personal Paint Rexx port could not be opened'
EXIT 10
END
ADDRESS VALUE PPPORT
OPTIONS RESULTS
OPTIONS FAILAT 10000
Get 'LANG'
IF RESULT = 1 THEN DO /* Deutsch */
txt_title_req = 'GIF-Anim-Brush speichern'
txt_title_set = 'GIF-Anim-Brush-Einstellungen'
txt_title_delay = 'Frame-Verzögerung'
txt_gad_delay = 'Frame-Verzögerungen:'
txt_gad_annot = '_Bemerkung:'
txt_gad_loop = '_Schleife:'
txt_gad_useloop = 'Schleife ak_tiv:'
txt_gad_transp = '_Transparenz:'
txt_gad_del = '_Verzögerung:'
txt_gad_deltype = ' '
txt_gad_deltype0 = '1/100\""'
txt_gad_deltype1 = 'Von Animation'
txt_gad_from = 'A_b Frame:'
txt_gad_to = 'Bi_s Frame:'
txt_err_oldclient = 'Für dieses Skript_ist eine neuere Version_von Personal Paint erforderlich'
txt_err_oldlib = 'Für dieses Skript ist eine neuere Version_der GIF library erforderlich'
txt_err_notabsh = 'Aktueller Brush_ist kein Anim-Brush'
txt_err_notemp = 'Zu wenig Speicher_für temporären Brush'
txt_err_nomem = 'Speichermangel'
txt_err_nosave = 'Fehler bei Datei-Ein-/Ausgabe'
END
ELSE IF RESULT = 2 THEN DO /* Italiano */
txt_title_req = 'Scrivere Anim-brush GIF'
txt_title_set = 'Parametri Anim-brush GIF'
txt_title_delay = 'Temporizzazione'
txt_gad_delay = 'Temporizzazione fotogrammi:'
txt_gad_annot = '_Note:'
txt_gad_loop = 'Cic_lo:'
txt_gad_useloop = '_Usare ciclo:'
txt_gad_transp = '_Transparenza:'
txt_gad_del = '_Temporizzazione:'
txt_gad_deltype = ' '
txt_gad_deltype0 = '1/100\""'
txt_gad_deltype1 = 'Da animazione'
txt_gad_from = 'Da _fotogramma:'
txt_gad_to = 'A f_otogramma:'
txt_err_oldclient = 'Questa procedura richiede_una versione più recente_di Personal Paint'
txt_err_oldlib = 'Questa procedura richiede_una versione più recente_della libreria GIF'
txt_err_notabsh = 'Il pennello attuale_non è un anim-brush'
txt_err_notemp = 'Impossibile creare_pennello temporaneo'
txt_err_nomem = 'Memoria insufficiente'
txt_err_nosave = 'Errore di scrittura'
END
ELSE DO /* English */
txt_title_req = 'Save GIF Anim-Brush'
txt_title_set = 'GIF Anim-Brush Settings'
txt_title_delay = 'Frame Delay'
txt_gad_delay = 'Frame Delays:'
txt_gad_annot = '_Annotation:'
txt_gad_loop = '_Loop:'
txt_gad_useloop = '_Use Loop:'
txt_gad_transp = '_Transparency:'
txt_gad_del = '_Delay:'
txt_gad_deltype = ' '
txt_gad_deltype0 = '1/100\""'
txt_gad_deltype1 = 'From Animation'
txt_gad_from = '_From Frame:'
txt_gad_to = 'T_o Frame:'
txt_err_oldclient = 'This script requires a newer_version of Personal Paint'
txt_err_oldlib = 'This script requires a newer_version of the GIF library'
txt_err_notabsh = 'The current brush_is not an anim-brush'
txt_err_notemp = 'No space for temporary brush'
txt_err_nomem = 'Not enough memory'
txt_err_nosave = 'File I/O error'
END
Version 'REXX'
IF RESULT < 7 THEN DO
RequestNotify 'PROMPT "'txt_err_oldclient'"'
EXIT 10
END
LockGUI
GetBrushAttributes 'FRAMES'
frames = RESULT
IF frames < 2 THEN DO
RequestNotify 'PROMPT "'txt_err_notabsh'"'
UnlockGUI
EXIT 0
END
GetBrushNumber
bshnum = RESULT
SetCurrentBrush 'UNUSED'
IF RC ~= 0 THEN DO
RequestNotify 'PROMPT "'txt_err_notemp'"'
UnlockGUI
EXIT 0
END
GetBrushNumber
tbshnum = RESULT
SetCurrentBrush 'BRUSH' bshnum
GetBrushInfo 'ANNOTATION'
frame_annot = RESULT
loop = -1
delay. = 0
IF WORD(frame_annot, 1) = 'LOOP' & WORD(frame_annot, 3) = 'DELAY' THEN DO
loop = WORD(frame_annot, 2)
IF ~DATATYPE(loop, 'W') THEN
loop = -1
DO frm = 1 TO frames
del = WORD(frame_annot, 3+frm)
IF DATATYPE(del, 'W') THEN
delay.frm = del
END
END
use_loop = (loop >= 0)
IF loop < 0 THEN
loop = 0
fnlen = LENGTH(frames)
dsel = 1
do_req = 1
deltype = 0
GetBrushInfo 'COPYRIGHT'
annot = RESULT
max_annot_size = LENGTH(annot) * 2
IF max_annot_size < 200 THEN
max_annot_size = 200
GetBrushAttributes 'TRANSPARENCY'
transp = RESULT
IF transp ~= 1 THEN
transp = 0
DO WHILE do_req
ppos = 1
DO FOREVER
ppos = INDEX(annot, '"', ppos)
IF ppos = 0 THEN BREAK
annot = INSERT('\"', annot, ppos-1)
ppos = ppos + 3
END
req = '"LIST ACTION = ""'txt_gad_delay'"", 'frames', 'dsel-1', 20, 7'
DO frm = 1 TO frames
req = req || ', ""'RIGHT(frm, fnlen) || ':' delay.frm || '""'
END
req = req ||,
' STRING = ""'txt_gad_annot'"", 'max_annot_size', ""'annot'"" ' ||,
' INTSTR = ""'txt_gad_loop'"", 0, 32767, 'loop' ' ||,
' CHECK = ""'txt_gad_useloop'"", 'use_loop' ' ||,
' CHECK = ""'txt_gad_transp'"", 'transp' "'
Request 'RESIZE "'txt_title_set'"' req
IF RC = 0 THEN DO
dsel = RESULT.1 + 1
annot = RESULT.2
loop = RESULT.3
use_loop = RESULT.4
transp = RESULT.5
IF RESULT = -1 THEN DO
Request '"'txt_title_delay'" ' ||,
'"INTSTR = ""'txt_gad_del'"", 0, 32767, 'delay.dsel' ' ||,
' CYCLE = ""'txt_gad_deltype'"", 2, 'deltype', ""'txt_gad_deltype0'"", ""'txt_gad_deltype1'"" ' ||,
' SEPARATOR ' ||,
' INTSTR = ""'txt_gad_from'"", 1, 'frames', 'dsel' ' ||,
' INTSTR = ""'txt_gad_to'"", 1, 'frames', 'dsel' "'
IF RC = 0 THEN DO
del = RESULT.1
deltype = RESULT.2
frfrom = RESULT.3
frto = RESULT.4
frstep = SIGN(frto - frfrom)
IF frstep = 0 THEN
frstep = 1
DO frm = frfrom TO frto BY frstep
IF deltype THEN DO
IF del < 1 THEN
del = 1
GetFrameDelay 'FRAME' del
IF RC = 0 THEN
delay.frm = TRUNC((RESULT * 100 / 60) + 0.5)
del = del + frstep
END
ELSE delay.frm = del
END
END
END
ELSE do_req = 0
END
ELSE DO
UnlockGUI
EXIT 0
END
END
IF ~use_loop THEN
loop = -1
frame_annot = 'LOOP' loop 'DELAY'
DO frm = 1 TO frames
frame_annot = frame_annot delay.frm
END
SetBrushInfo 'ANNOTATION "'frame_annot'"'
RequestFile '"'txt_title_req'" SAVEMODE'
IF RC = 0 THEN DO
PARSE VALUE RESULT WITH '"' fname '"'
tempfile = 'T:PP_AnGif.'PRAGMA('ID')
GetBrushAttributes 'FRAMEFIRST'
sv_frmin = RESULT
GetBrushAttributes 'FRAMELAST'
sv_frmax = RESULT
GetBrushAttributes 'LENGTH'
sv_frlen = RESULT
GetBrushAttributes 'FRAMEPOSITION'
sv_frpos = RESULT
Get 'ICONS'
sv_icons = RESULT
GetBrushAttributes 'WIDTH'
bwidth = RESULT
GetBrushAttributes 'HEIGHT'
bheight = RESULT
GetBrushAttributes 'TRANSPARENTCOLOR'
transpcol = RESULT
GetBrushAttributes 'COLORS'
bcolors = RESULT
plt_size = bcolors * 3
Get 'PATHBSH'
PARSE VAR RESULT '"' sv_pathbsh '"'
IF transp = 1 THEN
pckinfo = '09'x
ELSE
pckinfo = '00'x
DO bdepth = 1 TO 8
IF bcolors = (2 ** bdepth) THEN
BREAK
END
tbmap.0 = 0
tbmap.1 = 0
tbnum = 0
gfile_open = 0
global_plt = ''
err_msg = ''
SIGNAL ON Break_C
AllocateBitmap bwidth bheight bdepth
IF RC = 0 THEN DO
tbmap.0 = RESULT
AllocateBitmap bwidth bheight bdepth
IF RC = 0 THEN DO
tbmap.1 = RESULT
SetBrushAttributes 'FRAMEFIRST 1 FRAMELAST' frames 'LENGTH' frames
Set '"ICONS = 0"'
DO frm = 1 TO frames
SetCurrentBrush 'BRUSH' bshnum
IF RC ~= 0 THEN DO
err_msg = txt_err_nomem
BREAK
END
SetBrushAttributes 'FRAMEPOSITION' frm
IF RC ~= 0 THEN DO
err_msg = txt_err_nomem
BREAK
END
GetBitmap '0 0 BITMAP' tbmap.tbnum 'FROMBRUSH'
tbnum = 1 - tbnum
GetBrushColors
local_plt = RESULT
IF frm = 1 THEN DO
dx0 = 0
dy0 = 0
dx1 = bwidth - 1
dy1 = bheight - 1
global_plt = local_plt
END
ELSE DO
IF transp = 1 THEN
GetBrushAttributes 'BOUNDARIES'
ELSE
GetBitmapDelta tbmap.0 tbmap.1
PARSE VAR RESULT dx0 dy0 dx1 dy1 .
IF dx0 < 0 THEN DO
dx0 = 0
dy0 = 0
dx1 = 0
dy1 = 0
END
IF transp ~= 1 & global_plt ~== local_plt THEN DO /* IExplorer bug */
dx0 = 0
dy0 = 0
dx1 = bwidth - 1
dy1 = bheight - 1
END
END
SetCurrentBrush 'BRUSH' tbshnum
IF RC ~= 0 THEN DO
err_msg = txt_err_nomem
BREAK
END
CopyBrush bshnum dx0 dy0 dx1 dy1 'NOFRAMES'
IF RC ~= 0 THEN DO
err_msg = txt_err_nomem
BREAK
END
SaveBrush tempfile 'FORCE QUIET NOPROGRESS FORMAT "GIF" OPTIONS "GIF89=1" "PROGDSP=0" "SCRFMT=0"'
IF RC ~= 0 THEN DO
IF RC = 46 | RC = 47 THEN
err_msg = txt_err_oldlib
ELSE
err_msg = txt_err_nosave
BREAK
END
IF ~OPEN('tfile', tempfile, 'R') THEN DO
err_msg = txt_err_nosave
BREAK
END
IF frm = 1 THEN DO
IF ~OPEN('gfile', fname, 'W') THEN DO
err_msg = txt_err_nosave
BREAK
END
gfile_open = 1
data = READCH('tfile', 13) /* sign + screen descriptor */
bxpix = BITOR(BITAND(SUBSTR(data, 11, 1), '07'x), '80'x)
CALL WRITECH('gfile', data)
plt_data = READCH('tfile', plt_size) /* palette */
CALL WRITECH('gfile', plt_data)
do_plt = 0
IF use_loop THEN
CALL WRITECH('gfile', '21FF0B'x || 'NETSCAPE2.0' || '0301'x || IntelWord(loop) || '00'x)
IF annot ~= '' THEN DO /* annotation */
CALL WRITECH('gfile', '21FE'x)
alen = LENGTH(annot)
apos = 1
DO WHILE alen > 0
IF alen <= 255 THEN
aln = alen
ELSE
aln = 255
CALL WRITECH('gfile', D2C(aln) || SUBSTR(annot, apos, aln))
apos = apos + aln
alen = alen - aln
END
CALL WRITECH('gfile', '00'x)
END
END
ELSE DO
CALL SEEK('tfile', 13, 'B')
plt_data = READCH('tfile', plt_size)
do_plt = (global_plt ~== local_plt)
END
DO FOREVER
code = READCH('tfile', 1)
IF code = ',' THEN DO /* image */
/* gfx control */
CALL WRITECH('gfile', '21F904'x || pckinfo || IntelWord(delay.frm) || D2C(transpcol) || '00'x)
data = READCH('tfile', 9) /* Get image descriptor */
imginfo = SUBSTR(data, 9, 1)
IF do_plt THEN
imginfo = BITOR(BITAND(imginfo, '40'x), bxpix)
/* image descriptor */
CALL WRITECH('gfile', ',' || IntelWord(dx0) || IntelWord(dy0) || IntelWord(dx1-dx0+1) || IntelWord(dy1-dy0+1) || imginfo)
IF do_plt THEN
CALL WRITECH('gfile', plt_data)
tpos = SEEK('tfile', 0, 'C')
epos = SEEK('tfile', 0, 'E')
dsize = epos - tpos - 1
CALL SEEK('tfile', tpos, 'B')
/* image data */
DO WHILE dsize > 0
IF dsize > 65000 THEN
tsize = 65000
ELSE
tsize = dsize
data = READCH('tfile', tsize)
CALL WRITECH('gfile', data)
dsize = dsize - tsize
END
BREAK
END
ELSE IF code = '!' THEN DO /* extension */
CALL SEEK('tfile', 1, 'C')
length = 1
DO WHILE length ~= 0
length = C2D(READCH('tfile', 1))
IF length > 0 THEN
CALL SEEK('tfile', length, 'C')
END
END
ELSE BREAK
END
CALL CLOSE('tfile')
END
CALL WRITECH('gfile', ';')
CALL CLOSE('gfile')
gfile_open = 0
ADDRESS COMMAND 'Delete >NIL: 'tempfile
SetCurrentBrush 'BRUSH' tbshnum
IF RC = 0 THEN
FreeBrush 'FORCE'
SetCurrentBrush 'BRUSH' bshnum
IF RC = 0 THEN
SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
Set '"ICONS =' sv_icons '"'
FreeBitmap tbmap.1
END
ELSE err_msg = txt_err_nomem
FreeBitmap tbmap.0
END
ELSE err_msg = txt_err_nomem
IF err_msg ~= '' THEN
RequestNotify 'PROMPT "'err_msg'"'
Set '"PATHBSH=""'sv_pathbsh'"" "'
END
UnlockGUI
EXIT 0
IntelWord: PROCEDURE
value = ARG(1)
hibyte = value % 256
lobyte = value - (hibyte * 256)
RETURN D2C(lobyte) || D2C(hibyte)
Break_C:
IF gfile_open THEN
CALL CLOSE('gfile')
ADDRESS COMMAND 'Delete >NIL: 'tempfile
SetCurrentBrush 'BRUSH' tbshnum
IF RC = 0 THEN
FreeBrush 'FORCE'
SetCurrentBrush 'BRUSH' bshnum
IF RC = 0 THEN
SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
Set '"ICONS =' sv_icons '"'
IF tbmap.1 ~= 0 THEN
FreeBitmap tbmap.1
IF tbmap.0 ~= 0 THEN
FreeBitmap tbmap.0
Set '"PATHBSH=""'sv_pathbsh'"" "'
RETURN